/* Peter Banda, Daniel Cristofani, Dominic Tippabattuni                     */
/* 975530978    971012079          958842138                                */
/* VMM_Sim Implementation (assignment 5)                                    */
/* CS 538, Portland State University, Fall 2010                             */
/* Turned in November 18, 2010                                              */

/* main.c contains some common functions and the (small) main program.      */

#include "vmm.h"

//Terminate with specified error. Made with variable number of arguments,
//so we can feed it printf-type parameters.
void error(char *string, ...)
{
    va_list ap;
    va_start(ap, string);
    fprintf(stderr, "Error: ");
    vfprintf(stderr, string, ap);
    fprintf(stderr, "\n");
    exit(1);
}

//Report specified error, but do not teminate.
void warning(char *string, ...)
{
    va_list ap;
    va_start(ap, string);
    fprintf(stderr, "Warning: ");
    vfprintf(stderr, string, ap);
    fprintf(stderr, "\n");
}

//Report specified data, if DEBUG is #defined as nonzero.
void debug(char *string, ...)
{
    va_list ap;
    if(DEBUG){
        va_start(ap, string);
        fprintf(stderr, "Debug: ");
        vfprintf(stderr, string, ap);
        fprintf(stderr, "\n");
    }
}


//sets the number of page frames to be used by the VMM
void setNoOfPageFrames(int num)
{
    if (num < 3) {
	warning("3 is the minimum number of page frames required. Allocating 3 page frames.");
	num=3;
    }
    noOfPageFrames = num;
}

// checks a string of the form -tvx and sets the debug flags. 
// returns 0 on successful completion. 
// returns 1 if the command is p, to indicate that the value should be read in
// the next argument

int setDebugFlags(char *debugOption)
{
    int i;
    int ret = 0;

    for (i = 1; debugOption[i] != '\0'; i++) {
	switch (debugOption[i]) {
	case 'v':
	case 'V':
            printVersionInfo();
	    break;
	case 'l':
	case 'L':
	    lFlag=true;
	    break;
	case 't':
	case 'T':
	    tFlag=true;
	    break;
	case 'p':
	case 'P':
	    return 1;		// check for the value in the next argument
	    break;
	default:
	    warning("debug option not recognized: %c\n", debugOption[i]);
	}
    }
    return ret;			// debug options read successfully in this argument
}

//The main program. Very simple; other modules do most of the work.
int main(int argc, char *argv[])
{
    int i, ret;

// read and set debug options,if any, from command line arguments
    for (i = 1; i < argc; i++) {
	if (argv[i][0] == '-') {
	    ret = setDebugFlags(argv[i]);

	    // ret == 1 implies p command. read noOfFrames in the next argument 
	    if (ret == 1) {
		if (++i < argc)
		    setNoOfPageFrames(atoi(argv[i]));
		else
		    warning
			("-p command used without any value. Simulating using default no of page frames");
	    }
	} else {
	    error
		("Incorrect command line argument, %s. Use '-' before the debug options",
		 argv[i]);
	}
    }
    inputHandler();
    printVMMStatistics();
    if(tFlag) printTraceInfo();
    exit(0);
}
